package com.example.udpdemo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * UDP客户端服务类
 * 用于发送UDP消息
 * 
 * @author demo
 */
@Service
public class UDPClientService {

    private static final Logger log = LoggerFactory.getLogger(UDPClientService.class);
    
    // 发送消息计数器
    private final AtomicInteger sentCount = new AtomicInteger(0);
    
    // 接收消息计数器
    private final AtomicInteger receivedCount = new AtomicInteger(0);

    /**
     * 发送UDP消息并等待响应
     */
    public String sendMessageWithResponse(String targetHost, int targetPort, String message, int timeout) {
        DatagramSocket socket = null;
        try {
            // 创建UDP Socket
            socket = new DatagramSocket();
            
            // 设置超时时间
            socket.setSoTimeout(timeout);
            
            // 解析目标地址
            InetAddress targetAddress = InetAddress.getByName(targetHost);
            
            // 将消息转换为字节数组
            byte[] sendData = message.getBytes(StandardCharsets.UTF_8);
            
            // 创建发送数据包
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress, targetPort);
            
            // 发送数据包
            socket.send(sendPacket);
            
            // 增加发送计数器
            int sentCount = this.sentCount.incrementAndGet();
            log.info("发送消息到 {}:{} [{}]: {}", targetHost, targetPort, sentCount, message);
            
            // 创建接收缓冲区
            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            
            // 接收响应
            socket.receive(receivePacket);
            
            // 解析响应数据
            String response = new String(receivePacket.getData(), 0, receivePacket.getLength(), StandardCharsets.UTF_8);
            
            // 增加接收计数器
            int receivedCount = this.receivedCount.incrementAndGet();
            log.info("收到来自 {}:{} 的响应 [{}]: {}", 
                    receivePacket.getAddress().getHostAddress(), 
                    receivePacket.getPort(), 
                    receivedCount, 
                    response);
            
            return response;
            
        } catch (Exception e) {
            log.error("发送UDP消息时发生异常", e);
            return "发送失败: " + e.getMessage();
        } finally {
            // 关闭Socket
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }

    /**
     * 发送UDP消息（不等待响应）
     */
    public boolean sendMessage(String targetHost, int targetPort, String message) {
        DatagramSocket socket = null;
        try {
            // 创建UDP Socket
            socket = new DatagramSocket();
            
            // 解析目标地址
            InetAddress targetAddress = InetAddress.getByName(targetHost);
            
            // 将消息转换为字节数组
            byte[] sendData = message.getBytes(StandardCharsets.UTF_8);
            
            // 创建发送数据包
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress, targetPort);
            
            // 发送数据包
            socket.send(sendPacket);
            
            // 增加发送计数器
            int sentCount = this.sentCount.incrementAndGet();
            log.info("发送消息到 {}:{} [{}]: {}", targetHost, targetPort, sentCount, message);
            
            return true;
            
        } catch (Exception e) {
            log.error("发送UDP消息时发生异常", e);
            return false;
        } finally {
            // 关闭Socket
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }

    /**
     * 广播UDP消息
     */
    public boolean broadcastMessage(String message, int targetPort) {
        DatagramSocket socket = null;
        try {
            // 创建UDP Socket
            socket = new DatagramSocket();
            
            // 设置广播权限
            socket.setBroadcast(true);
            
            // 广播地址
            InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
            
            // 将消息转换为字节数组
            byte[] sendData = message.getBytes(StandardCharsets.UTF_8);
            
            // 创建发送数据包
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcastAddress, targetPort);
            
            // 发送数据包
            socket.send(sendPacket);
            
            // 增加发送计数器
            int sentCount = this.sentCount.incrementAndGet();
            log.info("广播消息到 {}:{} [{}]: {}", 
                    broadcastAddress.getHostAddress(), targetPort, sentCount, message);
            
            return true;
            
        } catch (Exception e) {
            log.error("广播UDP消息时发生异常", e);
            return false;
        } finally {
            // 关闭Socket
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }

    /**
     * 获取发送消息数量
     */
    public int getSentCount() {
        return sentCount.get();
    }

    /**
     * 获取接收消息数量
     */
    public int getReceivedCount() {
        return receivedCount.get();
    }

    /**
     * 重置计数器
     */
    public void resetCounters() {
        sentCount.set(0);
        receivedCount.set(0);
        log.info("UDP客户端计数器已重置");
    }
} 